home *** CD-ROM | disk | FTP | other *** search
- /*
- * Client routines for Network News Tranfer Protocol ala RFC977
- *
- * Copyright 1990 Anders Klemets - SM0RGV, All Rights Reserved.
- * Permission granted for non-commercial copying and use, provided
- * this notice is retained.
- *
- * Changes copyright 1990 Bernie Roehl, All Rights Reserved.
- * Permission granted for non-commercial copying and use, provided
- * this notice is retained.
- *
- * Revision history:
- *
- * May 11, 1990 - br checked for invalid chars in news filenames
- *
- * May 10, 1990 - br changed date stamp in 'From ' lines to
- * seconds since GMT (to make parsing and expiry easier)
- *
- * May 9, 1990 - br added locking of nntp.dat and history files,
- * second parameter to NNTP DIR, fixed bug in updating of
- * nntp.dat
- *
- * early May, 1990 -- br added NNTP TRACE, NNTP DIR,
- * server-specific newsgroups and connection windows,
- * locking of newsgroup files using mlock() and rmlock(),
- * date stamping of 'From ' lines, increased stack space,
- * updating of nntp.dat only on successful sessions.
- *
- * July 19, 1990 pa0gri Delinted and cleaned up. (calls and includes)
- *
- */
- #include "global.h"
- #ifdef NNTP
- #include "files.h"
- #include "ctype.h"
- #include <time.h>
- #ifdef MSDOS
- #include <sys/timeb.h>
- #endif
- #include "timer.h"
- #include "socket.h"
- #include "usock.h"
- #include "commands.h"
- #include "smtp.h"
- #include "mailutil.h"
- #include "hardware.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: nntpcli.c,v 1.21 1997/09/07 21:18:28 root Exp root $";
- #endif
-
- #define NNTPMAXLEN 512
-
- struct nntpservers {
- struct timer nntpcli_t;
- char *name;
- char *groups;
- int lowtime, hightime; /* for connect window */
- struct nntpservers *next;
- };
-
- #define NULLNNTP (struct nntpservers *)NULL
-
- #define MAXGROUPDIRS 10
-
- extern int Smtpquiet;
- extern int mkdir (const char *pathname, mode_t mode);
-
- struct grouploc {
- char *prefix; /* e.g. comp, rec, net, talk, alt ... */
- char *directory; /* directory where these groups should be */
- };
-
- static struct grouploc groupdirs[MAXGROUPDIRS] =
- {
- {NULL, NULL} /*lint !e785 */
- };
-
- static struct nntpservers *Nntpservers = NULLNNTP;
- static char *Nntpgroups = NULLCHAR;
- static unsigned short nntptrace = 1;
- static int nntpquiet = 0;
- static char *News_spool = NULL;
- static int np_all = 0; /* non-zero if NNTPdir is a malloc'ed space */
- static char const *validchars = "abcdefghijklmnopqrstuvwxyz0123456789-_";
- static char nntpstring[] = "nntp";
- static char historystring[] = "history";
-
-
- static void nntptick (void *tp);
- static void nntp_job (int i1, void *tp, void *v1);
- static int gettxt (int s, FILE * fp);
- static int getreply (int s);
- static int getarticle (int s, char *msgid);
- static int dogroups (int argc, char *argv[], void *p);
- static int doadds (int argc, char *argv[], void *p);
- static int dodrops (int argc, char *argv[], void *p);
- static int dokicks (int argc, char *argv[], void *p);
- static int dolists (int argc, char *argv[], void *p);
- static int donntrace (int argc, char *argv[], void *p);
- static int donnquiet (int argc, char *argv[], void *p);
- static int dondir (int argc, char *argv[], void *p);
-
- /* Tracing levels:
- 0 - no tracing
- 1 - serious errors reported
- 2 - transient errors reported
- 3 - session progress reported
- 4 - actual received articles displayed
- */
-
- static struct cmds Nntpcmds[] =
- {
- { "addserver", doadds, 0, 3, "nntp addserver <nntpserver> <interval>"},
- { "directory", dondir, 0, 0, NULLCHAR},
- { "dropserver", dodrops, 0, 2, "nntp dropserver <nntpserver>"},
- { "groups", dogroups, 0, 0, NULLCHAR},
- { "kick", dokicks, 0, 2, "nntp kick <nntpserver>"},
- { "listservers", dolists, 0, 0, NULLCHAR},
- { "quiet", donnquiet, 0, 0, NULLCHAR},
- { "trace", donntrace, 0, 0, NULLCHAR},
- { NULLCHAR, 0, 0, 0, NULLCHAR}
- };
-
-
-
-
- int
- donntp (int argc, char *argv[], void *p)
- {
- return subcmd (Nntpcmds, argc, argv, p);
- }
-
-
-
- static int
- doadds (int argc, char *argv[], void *p OPTIONAL)
- {
- struct nntpservers *np;
-
- for (np = Nntpservers; np != NULLNNTP; np = np->next)
- if (stricmp (np->name, argv[1]) == 0)
- break;
-
- if (np == NULLNNTP) {
- np = (struct nntpservers *) callocw (1, sizeof (struct nntpservers));
-
- np->name = strdup (argv[1]);
- np->next = Nntpservers;
- Nntpservers = np;
- np->groups = NULLCHAR;
- np->lowtime = np->hightime = -1;
- np->nntpcli_t.func = nntptick; /* what to call on timeout */
- np->nntpcli_t.arg = (void *) np;
- }
-
- if (argc > 3) {
- int i;
-
- if (np->groups == NULLCHAR) {
- np->groups = mallocw (NNTPMAXLEN);
- *np->groups = '\0';
- }
- for (i = 3; i < argc; ++i) {
- if (isdigit (*argv[i])) {
- int lh, ll, hh, hl;
-
- sscanf (argv[i], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
- np->lowtime = lh * 100 + ll;
- np->hightime = hh * 100 + hl;
- } else if ((strlen (np->groups) + strlen (argv[i]) + 2) >= NNTPMAXLEN)
- tprintf ("Group list too long! Group '%s' ignored!\n", argv[i]);
- else { /* it's a group, and it fits... add it to list */
- if (*np->groups != '\0')
- strcat (np->groups, ",");
- strcat (np->groups, argv[i]);
- }
- }
- if (*np->groups == '\0') { /* No groups specified? */
- free (np->groups);
- np->groups = NULLCHAR;
- }
- }
- /* set timer duration */
- set_timer (&np->nntpcli_t, atol (argv[2]) * 1000L);
- start_detached_timer (&np->nntpcli_t); /* and fire it up */
- return 0;
- }
-
-
-
- static int
- dodrops (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
- {
- struct nntpservers *np, *npprev = NULLNNTP;
-
- for (np = Nntpservers; np != NULLNNTP; npprev = np, np = np->next)
- if (stricmp (np->name, argv[1]) == 0) {
- stop_timer (&np->nntpcli_t);
- free (np->name);
- if (np->groups)
- free (np->groups);
- if (npprev != NULLNNTP)
- npprev->next = np->next;
- else
- Nntpservers = np->next;
- free ((char *) np);
- return 0;
- }
- tputs ("No such server enabled.\n");
- return 0;
- }
-
-
-
- static int
- dolists (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- struct nntpservers *np;
-
- for (np = Nntpservers; np != NULLNNTP; np = np->next) {
- char tbuf[80];
-
- if (np->lowtime != -1 && np->hightime != -1)
- sprintf (tbuf, " -- %02d:%02d-%02d:%02d", np->lowtime / 100, np->lowtime % 100, np->hightime / 100, np->hightime % 100);
- else
- tbuf[0] = '\0';
- tprintf ("%-32s (%lu/%lu%s) %s\n", np->name,
- read_timer (&np->nntpcli_t) / 1000L,
- dur_timer (&np->nntpcli_t) / 1000L,
- tbuf, np->groups ? np->groups : "");
- }
- return 0;
- }
-
-
-
- static int
- donntrace (int argc, char *argv[], void *p OPTIONAL)
- {
- return setshort (&nntptrace, "NNTP tracing", argc, argv);
- }
-
-
-
- static int
- donnquiet (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&nntpquiet, "NNTP quiet", argc, argv);
- }
-
-
-
- static int
- dondir (int argc, char *argv[], void *vp OPTIONAL)
- {
- if (argc < 2) {
- int i;
-
- tprintf ("spool: %s\n", News_spool ? News_spool : Mailspool);
- tprintf ("control: %s\n", NNTPdir);
- for (i = 0; i < MAXGROUPDIRS; ++i)
- if (groupdirs[i].prefix)
- tprintf ("%-10.10s %s\n", groupdirs[i].prefix, groupdirs[i].directory);
- } else {
- char *p;
-
- if ((p = strchr (argv[1], '=')) != NULLCHAR) { /* set a groupdir */
- int i;
-
- *p++ = '\0';
- for (i = 0; i < MAXGROUPDIRS; ++i)
- if (groupdirs[i].prefix)
- if (!strnicmp (groupdirs[i].prefix, argv[1], strlen (argv[1]))) {
- if (groupdirs[i].directory) {
- free (groupdirs[i].directory);
- groupdirs[i].directory = NULLCHAR;
- }
- if (*p == '\0') {
- free (groupdirs[i].prefix);
- groupdirs[i].prefix = NULLCHAR;
- } else
- groupdirs[i].directory = strdup (p);
- return 0;
- }
- if (*p == '\0') /* trashing a group that's not there */
- return 0;
- for (i = 0; i < MAXGROUPDIRS; ++i) {
- if (groupdirs[i].prefix == NULLCHAR) {
- groupdirs[i].prefix = strdup (argv[1]);
- if (groupdirs[i].directory) {
- free (groupdirs[i].directory);
- groupdirs[i].directory = NULL;
- }
- groupdirs[i].directory = strdup (p);
- return 0;
- }
- }
- tputs ("Directory table full\n");
- } else { /* no '=', so just set default */
- if (News_spool)
- free (News_spool);
- News_spool = strdup (argv[1]);
- }
- if (argc > 2) { /* they specified a newsdir as well */
- if (np_all)
- free (NNTPdir);
- NNTPdir = strdup (argv[2]);
- np_all = 1;
- }
- }
- return 0;
- }
-
-
-
- static int
- dokicks (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
- {
- struct nntpservers *np;
-
- for (np = Nntpservers; np != NULLNNTP; np = np->next)
- if (stricmp (np->name, argv[1]) == 0) {
- /* If the timer is not running, the timeout function has
- * already been called and we don't want to call it again.
- */
- if (run_timer (&np->nntpcli_t))
- stop_timer (&np->nntpcli_t);
-
- nntptick ((void *) np);
- return 0;
- }
- tputs ("No such server enabled.\n");
- return 1;
- }
-
-
-
- static int
- dogroups (int argc, char *argv[], void *p OPTIONAL)
- {
- int i;
-
- if (argc < 2) {
- if (Nntpgroups == NULLCHAR || (Nntpgroups != NULLCHAR && strcmp (Nntpgroups, "*") == 0))
- tputs ("All groups are currently enabled.\n");
- else
- tprintf ("Currently enabled newsgroups:\n%s\n", Nntpgroups);
- return 0;
- }
- if (Nntpgroups == NULLCHAR)
- Nntpgroups = mallocw (NNTPMAXLEN);
- *Nntpgroups = '\0';
- for (i = 1; i < argc; ++i) {
- if (i > 1)
- strcat (Nntpgroups, ",");
- strcat (Nntpgroups, argv[i]);
- }
- return 0;
- }
-
-
-
- /* This is the routine that gets called every so often to connect to
- * NNTP servers.
- */
- static void
- nntptick (void *tp)
- {
- (void) newproc ("NNTP client", 3072, nntp_job, 0, tp, NULL, 0);
- }
-
-
-
- static void
- nntp_job (int i1 OPTIONAL, void *tp, void *v1 OPTIONAL)
- {
- FILE *fp, *tmpf;
- int s = -1, i;
- struct tm *ltm;
- time_t t;
- int now;
- struct nntpservers *np = (struct nntpservers *) tp;
- struct sockaddr_in fsocket;
- char tbuf[NNTPMAXLEN], buf[NNTPMAXLEN], *cp, *lastdate = NULLCHAR;
-
- if (nntptrace >= 3)
- tcmdprintf ("NNTP daemon entered, target = %s\n", np->name);
-
- (void) time (&t); /* more portable than gettime() */
- ltm = localtime (&t);
- now = ltm->tm_hour * 100 + ltm->tm_min;
- if (np->lowtime < np->hightime) { /* doesn't cross midnight */
- if (now < np->lowtime || now >= np->hightime) {
- if (nntptrace >= 3)
- tcmdprintf ("NNTP window to '%s' not open\n", np->name);
- start_detached_timer (&np->nntpcli_t);
- return;
- }
- } else {
- if (now < np->lowtime && now >= np->hightime) {
- if (nntptrace >= 3)
- tcmdprintf ("NNTP window to '%s' not open\n", np->name);
- start_detached_timer (&np->nntpcli_t);
- return;
- }
- }
-
- fsocket.sin_addr.s_addr = resolve (np->name);
- if (fsocket.sin_addr.s_addr == 0) { /* No IP address found */
- if (nntptrace >= 2)
- tcmdprintf ("NNTP can't resolve host '%s'\n", np->name);
- /* Try again later */
- start_detached_timer (&np->nntpcli_t);
- return;
- }
- fsocket.sin_family = AF_INET;
- fsocket.sin_port = IPPORT_NNTP;
-
- s = socket (AF_INET, SOCK_STREAM, 0);
- (void) sockmode (s, SOCK_ASCII);
- if (connect (s, (char *) &fsocket, SOCKSIZE) == -1) {
- const char *cp2;
-
- cp2 = sockerr (s);
- log (s, "NNTP %s Connect failed: %s", psocket (&fsocket),
- cp2 != NULLCHAR ? cp2 : "");
- if (nntptrace >= 2)
- tcmdprintf ("NNTP %s Connect failed: %s\n", psocket (&fsocket),
- cp2 != NULLCHAR ? cp2 : "");
- goto quit;
- }
- /* Eat the banner */
- i = getreply (s);
- if (i == -1 || i >= 400) {
- log (s, "NNTP %s bad reply on banner (response was %d)", psocket (&fsocket), i);
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s bad reply on banner (response was %d)\n", psocket (&fsocket), i);
- goto quit;
- }
- if (mlock (NNTPdir, nntpstring)) {
- if (nntptrace >= 2)
- tcmdprintf ("NNTP %s Connect failed: cannot lock nntp.dat\n", psocket (&fsocket));
- goto quit;
- }
- sprintf (buf, "%s/nntp.dat", NNTPdir);
- if ((fp = fopen (buf, UPDATE_TEXT)) == NULLFILE) {
- log (s, "NNTP %s Connect failed: Cannot open %s", psocket (&fsocket),
- buf);
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s Connect failed: Cannot open %s\n", psocket (&fsocket), buf);
- rmlock (NNTPdir, nntpstring);
- goto quit;
- }
- rewind (fp);
- /* for(pos=0L; fgets(buf,NNTPMAXLEN,fp) != NULLCHAR;pos=ftell(fp)) { */
- for (; fgets (buf, NNTPMAXLEN, fp) != NULLCHAR;) {
- if ((cp = strchr (buf, ' ')) == NULLCHAR)
- continue; /* something wrong with this line, skip it */
- *cp = '\0';
- if (stricmp (buf, np->name) == 0) {
- rip (cp + 1);
- lastdate = strdup (cp + 1);
- break;
- }
- }
- fclose (fp);
- rmlock (NNTPdir, nntpstring);
-
- if (lastdate == NULLCHAR)
- lastdate = strdup ("700101 000000");
- /* snapshot the time for use later in re-writing nntp.dat */
- (void) time (&t);
- ltm = localtime (&t);
-
- /* Get a list of new message-id's */
- if (np->groups) {
- if (nntptrace >= 3)
- tcmdprintf ("==>NEWNEWS %s %s\n", np->groups, lastdate);
- usprintf (s, "NEWNEWS %s %s\n", np->groups, lastdate);
- } else {
- if (nntptrace >= 3)
- tcmdprintf ("==>NEWNEWS %s %s\n", Nntpgroups != NULLCHAR ? Nntpgroups : "*", lastdate);
- usprintf (s, "NEWNEWS %s %s\n", Nntpgroups != NULLCHAR ? Nntpgroups : "*", lastdate);
- }
- free (lastdate);
- /* Get the response */
- if ((i = getreply (s)) != 230) { /* protocol error */
- log (s, "NNTP %s protocol error (response was %d)", psocket (&fsocket), i);
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s protocol error (response was %d)\n", psocket (&fsocket), i);
- goto quit;
- }
- if ((tmpf = tmpfile ()) == NULLFILE) {
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s Cannot open temp file\n", psocket (&fsocket));
- goto quit;
- }
- if (gettxt (s, tmpf) == -1) {
- log (s, "NNTP %s giving up: gettxt() failure", psocket (&fsocket));
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s giving up: gettxt() failure\n", psocket (&fsocket));
- fclose (tmpf);
- goto quit;
- }
- /* Open the history file */
- if (mlock (NNTPdir, historystring)) {
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s giving up: couldn't lock history file\n", psocket (&fsocket));
- fclose (tmpf);
- goto quit;
- }
- sprintf (buf, "%s/history", NNTPdir);
- if ((fp = fopen (buf, APPEND_TEXT)) == NULLFILE) {
- log (s, "NNTP %s Connect failed: Cannot open %s", psocket (&fsocket), buf);
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s Connect failed: Cannot open %s\n", psocket (&fsocket), buf);
- fclose (tmpf);
- goto quit;
- }
- /* search through the history file for matching message id's */
- rewind (tmpf);
- while (fgets (tbuf, NNTPMAXLEN, tmpf) != NULLCHAR) {
- i = 0;
- rewind (fp);
- while (fgets (buf, NNTPMAXLEN, fp) != NULLCHAR) {
- if (stricmp (buf, tbuf) == 0) {
- i = 1;
- break;
- }
- kwait (NULL);
- }
- if (i == 0) { /* not found, get the article */
- if (getarticle (s, tbuf) == -1) {
- log (s, "NNTP %s Giving up: could not get article", psocket (&fsocket));
- if (nntptrace >= 2)
- tcmdprintf ("NNTP %s Giving up: could not get article\n", psocket (&fsocket));
- fclose (fp);
- rmlock (NNTPdir, historystring);
- fclose (tmpf);
- goto quit;
- }
- fprintf (fp, "%s", tbuf); /* add the new message id */
- }
- }
- fclose (fp);
- rmlock (NNTPdir, historystring);
- fclose (tmpf);
- if (nntptrace >= 3)
- tcmdprintf ("==>QUIT\n");
- usprintf (s, "QUIT\n");
- /* Eat the response */
- (void) getreply (s);
- /* NOW, update the nntp.dat file */
- if (mlock (NNTPdir, nntpstring)) {
- if (nntptrace >= 2)
- tcmdprintf ("NNTP %s Could not lock nntp.dat for update\n", psocket (&fsocket));
- goto quit;
- }
- sprintf (buf, "%s/nntp.dat", NNTPdir);
- fp = fopen (buf, READ_TEXT);
- sprintf (buf, "%s/nntp.tmp", NNTPdir);
- if ((tmpf = fopen (buf, WRITE_TEXT)) == NULLFILE)
- if (nntptrace >= 1)
- tcmdprintf ("NNTP %s Cannot create temp file '%s'\n", psocket (&fsocket), buf);
- if (fp == NULLFILE || tmpf == NULLFILE) {
- log (s, "NNTP %s Could not update %s", psocket (&fsocket), buf);
- if (nntptrace >= 2)
- tcmdprintf ("NNTP %s Could not update %s\n", psocket (&fsocket), buf);
- if (fp)
- fclose (fp);
- if (tmpf)
- fclose (tmpf);
- rmlock (NNTPdir, nntpstring);
- goto quit;
- }
- while (fgets (tbuf, sizeof (tbuf), fp))
- if (strnicmp (tbuf, np->name, strlen (np->name)))
- fputs (tbuf, tmpf);
- fprintf (tmpf, "%s %02d%02d%02d %02d%02d%02d\n", np->name, ltm->tm_year % 100, ltm->tm_mon + 1,
- ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
- fclose (fp);
- fclose (tmpf);
- sprintf (buf, "%s/nntp.dat", NNTPdir);
- sprintf (tbuf, "%s/nntp.tmp", NNTPdir);
- (void) unlink (buf);
- (void) rename (tbuf, buf);
- rmlock (NNTPdir, nntpstring);
- quit:
- if (nntptrace >= 3)
- tcmdprintf ("NNTP daemon exiting\n");
- close_s (s);
- /* Restart timer */
- start_detached_timer (&np->nntpcli_t);
- return;
- }
-
-
-
- static int
- gettxt (int s, FILE *fp)
- {
- char buf[NNTPMAXLEN];
- int nlines;
-
- for (nlines = 0; recvline (s, (unsigned char *) buf, NNTPMAXLEN) != -1; ++nlines) {
- if (nntptrace >= 4)
- tcmdprintf ("<==%s", buf);
- if (strcmp (buf, ".\n") == 0) {
- if (nntptrace >= 3)
- tcmdprintf ("NNTP received %d lines\n", nlines);
- return 0;
- }
- /* check for escaped '.' characters */
- if (strcmp (buf, "..\n") == 0)
- fputs (".\n", fp);
- else
- fputs (buf, fp);
- }
- if (nntptrace >= 1)
- tcmdprintf ("NNTP receive error after %d lines\n", nlines);
- return -1;
- }
-
-
-
- static int
- getreply (int s)
- {
- char buf[NNTPMAXLEN];
- int response;
-
- while (recvline (s, (unsigned char *) buf, NNTPMAXLEN) != -1) {
- /* skip informative messages and blank lines */
- if (buf[0] == '\0' || buf[0] == '1')
- continue;
- sscanf (buf, "%d", &response);
- if (nntptrace >= 3)
- tcmdprintf ("<==%s\n", buf);
- return response;
- }
- if (nntptrace >= 3)
- tcmdprintf ("==No response\n");
- return -1;
- }
-
-
-
- static int
- getarticle (int s, char *msgid)
- {
- char buf[NNTPMAXLEN], froml[NNTPMAXLEN], newgl[NNTPMAXLEN];
- FILE *fp, *tmpf;
- int r;
- char *cp;
- time_t t;
-
-
- if (nntptrace >= 3)
- tcmdprintf ("==>ARTICLE %s", msgid);
- usprintf (s, "ARTICLE %s", msgid);
- r = getreply (s);
- if (r == -1 || r >= 500)
- return -1;
- if (r >= 400)
- return 0;
- if ((tmpf = tmpfile ()) == NULLFILE) {
- if (nntptrace >= 1)
- tcmdprintf ("NNTP Cannot open temp file for article\n");
- return -1;
- }
- if (gettxt (s, tmpf) == -1) {
- fclose (tmpf);
- return -1;
- }
- /* convert the article into mail format */
- rewind (tmpf);
- froml[0] = '\0';
- newgl[0] = '\0';
- while (fgets (buf, NNTPMAXLEN, tmpf) != NULLCHAR) {
- if (strncmp (buf, Hdrs[FROM], 6) == 0) {
- (void) time (&t);
- rip (&buf[6]);
- sprintf (froml, "From %s %ld\n", &buf[6], t);
- if (newgl[0] != '\0')
- break;
- }
- if (strncmp (buf, Hdrs[NEWSGROUPS], 12) == 0) {
- strncpy (newgl, &buf[12], NNTPMAXLEN);
- if (froml[0] != '\0')
- break;
- }
- /* invalid article - missing 'From:' line or 'Newsgroups:' line */
- if (strcmp (buf, "\n") == 0 && (froml[0] == '\0' || newgl[0] == '\0')) {
- /* fclose(fp); */
- fclose (tmpf);
- return 0;
- }
- }
- sprintf (buf, "%s/", News_spool ? News_spool : Mailspool);
- for (cp = newgl;; ++cp) {
- if (*cp == '.') {
- mkdir (buf, 0755); /* create a subdirectory, if necessary */
- strcat (buf, "/");
- continue;
- }
- if (*cp == ',' || *cp == '\n') {
- char tempdir[80], prefix[20], *p;
-
- strncpy (tempdir, buf, 80);
- if ((p = strrchr (tempdir, '/')) != NULLCHAR) {
- *p++ = '\0';
- strncpy (prefix, p, 20);
- }
- if (mlock (tempdir, prefix)) {
- if (nntptrace >= 2)
- tcmdprintf ("NNTP group '%s' is locked\n", buf);
- return -1;
- }
- strcat (buf, ".txt");
- /* open the mail file */
- if (nntptrace >= 3)
- tcmdprintf ("Writing article to '%s'\n", buf);
- if ((fp = fopen (buf, APPEND_TEXT)) != NULLFILE) {
- fputs (froml, fp);
- #ifdef USERLOG
- /* If the userlog code is enabled, we need a
- * "Received: " line to get the message id
- * that is used in it - WG7J
- */
- time (&t);
- fprintf (fp, Hdrs[RECEIVED]);
- fprintf (fp, "by %s with NNTP\n\tid AA%ld ; %s",
- Hostname, get_msgid (0), ptime (&t));
- #endif
- rewind (tmpf);
- while (fgets (buf, NNTPMAXLEN, tmpf) != NULLCHAR) {
- /* for UNIX mail compatiblity */
- if (strncmp (buf, "From ", 5) == 0)
- putc ('>', fp);
- fputs (buf, fp);
- }
- putc ('\n', fp);
- fclose (fp);
- }
- rmlock (tempdir, prefix);
- if (*cp == '\n')
- break;
- else
- sprintf (buf, "%s/", News_spool ? News_spool : Mailspool);
- continue;
- }
- buf[strlen (buf) + 1] = '\0';
- buf[strlen (buf)] = strchr (validchars, tolower (*cp)) ? *cp : '_';
- }
- fclose (tmpf);
- strncpy (buf, msgid, NNTPMAXLEN); /* Get a copy we can munge */
- rip (buf); /* remove trailing new-line */
- rip (newgl); /* ditto */
- if (!nntpquiet)
- tprintf ("New news arrived: %s, article %s%c\n", newgl, buf, Smtpquiet ? ' ' : '\007');
- return 0;
- }
-
- #endif /* NNTP */
-